//
//  protect_inheritance.hpp
//  learnC++
//
//  Created by liuzhibing on 2018/6/12.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#ifndef protect_inheritance_hpp
#define protect_inheritance_hpp

#include <stdio.h>
#include <iostream>

class Base2 {
    
public:
    //继承者可以访问该属性，外界调用可以访问该属性
    int m_public;
    
protected:
    //继承者可以访问该属性，外界调用无法访问
    int m_protect;
    
private:
    //继承者无法访问该属性，外界调用无法访问
    int m_private;
    

    friend std::ostream &operator<<(std::ostream &out,const Base2 &base){
        out << "In Base\n";
        out << base.m_public << '\n';
        return out;
    }
    
};
//如果不选择继承类型，C ++将默认为私有继承（就像成员默认为私有访问一样，如果不另外指定）。
//class Derived2 : Base2 = class Derived2 : private Base2
class Derived2 : public Base2 {
    
    
public:
    Derived2(){
        m_public = 0;//allow
        m_protect = 0;//allow
//        m_private = 0;//not allow
    }
    
    //    当尝试在基类中调用好友函数时，我们可能会碰到一点小技巧，例如operator <<。 因为基类的友元函数实际上并不是基类的一部分，所以使用范围解析限定符将不起作用。 相反，我们需要一种方法来使Derived类暂时看起来像Base类，以便可以调用正确的函数版本。
    friend std::ostream &operator<<(std::ostream &out,const Derived2 &der){
        out << "In Derived2\n";
        out << static_cast<Base2>(der);
        return out;
    }
    
//    http://www.learncpp.com/cpp-tutorial/11-6a-calling-inherited-functions-and-overriding-behavior/
    
};


/*
 Base base;
 base.m_public = 1; // allowed: can access public members from outside class
 base.m_private = 2; // not allowed: can not access private members from outside class
 base.m_protected = 3; // not allowed: can not access protected members from outside class
 */



#endif /* protect_inheritance_hpp */
